/*
 * @Author: zhuxiaoyi
 * @Date: 2024-04-24 10:58:11
 * @LastEditor: zhuxiaoyi
 * @LastEditTime: 2025-09-27 11:41:49
 * @Description:
 */
import { Provide, App, Inject, Config } from '@midwayjs/core';
import { Ipage, IGraph, IAlgorithmParams } from '../interface';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Graph } from '../entity/graph.entity';
import { Application } from '@midwayjs/ws';
import { MiniTask } from '../entity/miniTask.entity';
import { Algorithm } from '../entity/algorithm.entity';
import { M1Product } from '../entity/module1.entity';
import { Task } from '../entity/task.entity';
import { Repository, Like } from 'typeorm';
import * as childProcess from 'child_process';
import { PromiseService } from '../service/promise.service';
import { TaskService } from './task.service';
import { SoilEtResult } from '../entity/detection-results.entity'
import axios from 'axios';
const http = require('http');
import * as fs from 'fs';
import { promises as fs1, createReadStream } from 'fs';
import * as path from 'path';
import * as archiver from 'archiver';
import { Console } from 'console';
const { v4: uuidv4 } = require('uuid');
import * as FormData from 'form-data';
import fetch from 'node-fetch';
const RsaEncryptUtil = require('../utils/RsaEncryptUtil');
@Provide()
export class GraphService {
  @InjectEntityModel(Graph)
  GraphModel: Repository<Graph>;

  @InjectEntityModel(MiniTask)
  MiniTaskModel: Repository<MiniTask>;

  @InjectEntityModel(Algorithm)
  AlgorithmModel: Repository<Algorithm>;

  @Inject()
  promiseService: PromiseService;

  @InjectEntityModel(Task)
  taskModel: Repository<Task>;

  @Inject()
  taskService: TaskService;

  @InjectEntityModel(SoilEtResult)
  SoilEtResultModel: Repository<SoilEtResult>;

  @App('webSocket')
  wsApp: Application;

  @Config('matlabExePath')
  matlabExePath;

  @Config('ArcGISPythonURL')
  ArcGISPythonURL;

  @Config('PythonURL')
  PythonURL;

  @Config('matlabRuntimeParamPath')
  matlabRuntimeParamPath;

  @Config('renbaoBaseURL')
  renbaoBaseURL;

  @Config('geoServerURL')
  geoServerURL;

  async getGraphList(params: Ipage) {
    const [result, total] = await this.GraphModel.findAndCount({
      where: { name: Like(`%${params.keyword ? params.keyword : ''}%`) },
      skip: (params.page_index - 1) * params.page_size,
      take: params.page_size,
      order: { createDate: 'DESC' },
    });
    return {
      succes: true,
      data: result,
      total,
      message: '成功',
    };
  }

  async getGraphsByType(id) {
    const graphs = await this.GraphModel.find({
      where: {
        type: id,
      },
      order: { createDate: 'DESC' },
    });
    if (graphs.length < 1) {
      return {
        succes: false,
        message: '未查询到算法流程',
      };
    }
    return { success: true, data: graphs, message: '算法流程查询成功 ' };
  }

  async getGraph(id: number) {
    const graph = await this.GraphModel.findOne({
      where: {
        id,
      },
    });
    if (!graph) {
      return {
        succes: false,
        message: '未查询到算法流程',
      };
    }
    return { success: true, data: graph, message: '算法流程查询成功 ' };
  }
  async getDynamicData(id: number) {
    const graph = await this.GraphModel.findOne({
      where: {
        id,
      },
    });
    if (!graph) {
      return {
        succes: false,
        message: '未查询到算法流程',
      };
    }
    return { success: true, data: JSON.parse(graph.dynamic), message: '流程模板字符串查询成功 ' };
  }
  async editDynamicData(id: number, dynamicData: any) {
    const graph = await this.GraphModel.findOne({
      where: {
        id,
      },
    });
    if (!graph) {
      return {
        succes: false,
        message: '未查询到算法流程',
      };
    }
    graph.dynamic = JSON.stringify(dynamicData)
    const graphResult = await this.GraphModel.save(graph);
    return { success: true, data: graphResult, message: '流程模板字符串查询成功 ' };
  }


  async addGraph(params: IGraph) {
    let graphData = JSON.parse(params.graph);
    let edges = [];
    let nodes = [];

    graphData.cells.forEach(element => {
      if (element.shape == 'edge') {
        edges.push(element);
      } else {
        nodes.push(element);
      }
    });
    const executionOrder = this.topologicalSort(edges);
    let graph = new Graph();
    graph.name = params.name;
    graph.graph = params.graph;
    graph.flow = JSON.stringify(executionOrder);
    const graphResult = await this.GraphModel.save(graph);
    if (graphResult) {
      this.createMiniTask(executionOrder, graphData, graph);
      return { success: true, data: graphResult, message: '图谱保存成功 ' };
    } else {
      return { success: false, message: '图谱保存失败 ' };
    }
  }

  /* 
  @isCopyed 是否为自动拷贝
  */
  async copyGraph(id: number, isCopyed, task_id: string = new Date().toString()) {
    const originGraph = await this.GraphModel.findOne({
      where: {
        id,
      },
    });
    if (!originGraph) {
      return {
        succes: false,
        message: '未查询到要拷贝的算法流程',
      };
    }

    let graphData = JSON.parse(originGraph.graph);
    let { newGraphData, newFlowOrder } = this.replaceUUIDs(graphData, JSON.parse(originGraph.flow));
    let graph = new Graph();
    graph.name = originGraph.name + '_' + task_id;
    graph.desc = originGraph.desc;
    graph.graph = newGraphData;
    graph.type = originGraph.type;
    graph.dynamic = originGraph.dynamic;
    graph.flow = JSON.stringify(newFlowOrder);
    graph.isCopyed = isCopyed;
    const graphResult = await this.GraphModel.save(graph);
    if (graphResult) {
      await this.batchCopyMiniTask(JSON.parse(originGraph.flow), newFlowOrder, graph);
      return { success: true, data: graphResult, message: '图谱复制成功 ' };
    } else {
      return { success: false, message: '图谱复制失败 ' };
    }
  }


  async batchCopyMiniTask(originFlow: string[], newFlow: string[], newGraph: Graph) {
    // 遍历原有的执行顺序,创建对应的子任务
    for (let i = 0; i < originFlow.length; i++) {
      const originId = originFlow[i];
      const newId = newFlow[i];

      // 查找原有的子任务
      const originMiniTask = await this.MiniTaskModel.findOne({
        where: {
          id: originId,
        },
      });

      if (originMiniTask) {
        // 创建新的子任务
        const newMiniTask = new MiniTask();
        newMiniTask.id = newId;
        newMiniTask.graphId = newGraph.id;
        newMiniTask.algorithmId = originMiniTask.algorithmId;
        newMiniTask.runTimeParams = originMiniTask.runTimeParams;
        newMiniTask.pause = originMiniTask.pause;

        // 保存新的子任务
        await this.MiniTaskModel.save(newMiniTask);
      }
    }
  }

  replaceUUIDs(graphData, originalFlow) {
    const newGraphData = JSON.parse(JSON.stringify(graphData));
    const idMap = {};

    newGraphData.cells.forEach(element => {
      const newId = uuidv4();
      idMap[element.id] = newId;
      element.id = newId;
    });

    newGraphData.cells.forEach(element => {
      if (element.shape === 'edge') {
        element.source.cell = idMap[element.source.cell];
        element.target.cell = idMap[element.target.cell];
      }
    });

    const newFlowOrder = originalFlow.map(uuid => idMap[uuid]);
    return {
      newGraphData,
      newFlowOrder
    };
  }


  async updateGraph(params: IGraph) {
    let graphData = JSON.parse(params.graph);
    let edges = [];
    let nodes = [];

    graphData.cells.forEach(element => {
      if (element.shape == 'edge') {
        edges.push(element);
      } else {
        nodes.push(element);
      }
    });
    const executionOrder = this.topologicalSort(edges);

    const graph = await this.GraphModel.findOne({
      where: {
        id: params.id,
      },
    });
    if (!graph) {
      return {
        succes: false,
        message: '未查询到算法流程',
      };
    }
    graph.name = params.name;
    graph.graph = params.graph;
    let diffResult;
    diffResult = await this.findArrayDiff(
      JSON.parse(graph.flow),
      executionOrder
    );
    graph.flow = JSON.stringify(executionOrder);
    const graphResult = await this.GraphModel.save(graph);
    if (graphResult) {
      this.createMiniTask(diffResult.added, graphData, graph);
      this.deleteMiniTask(diffResult.removed);
      return { success: true, data: graphResult, message: '图谱编辑成功 ' };
    } else {
      return { success: false, message: '图谱编辑失败 ' };
    }
  }

  async findArrayDiff(A, B) {
    const added = [];
    const removed = [];
    const common = [];

    for (const element of B) {
      if (!A.includes(element)) {
        added.push(element);
      }
    }

    for (const element of A) {
      if (!B.includes(element)) {
        removed.push(element);
      } else {
        common.push(element);
      }
    }
    console.log(added);
    console.log(removed);
    console.log(common);
    return { added, removed, common };
  }

  createMiniTask(executionOrder: string[], graphData: any, graph: Graph) {
    executionOrder.length > 0 &&
      executionOrder.forEach(async id => {
        let node = graphData.cells.find(item => {
          return item.id == id;
        });
        const algorithm = await this.AlgorithmModel.findOne({
          where: {
            id: node.data.id,
          },
        });
        let miniTask = new MiniTask();
        miniTask.id = node.id;
        miniTask.graphId = graph.id;
        miniTask.algorithmId = node.data.id;
        miniTask.runTimeParams = algorithm.parameters;
        miniTask.pause = false;
        this.MiniTaskModel.save(miniTask);
      });
  }

  deleteMiniTask(executionOrder) {
    executionOrder.length > 0 &&
      executionOrder.forEach(async id => {
        const miniTask = await this.MiniTaskModel.findOne({
          where: {
            id,
          },
        });
        let result = await this.MiniTaskModel.remove(miniTask);
        return {
          succes: true,
          data: result,
          message: '删除成功',
        };
      });
  }

  async executeGraph(id: number) {
    const graph = await this.GraphModel.findOne({
      where: {
        id,
      },
    });
    if (!graph) {
      return {
        succes: false,
        message: '未查询到算法流程',
      };
    }
    let task = await this.taskService.createTaskByGraph(graph)
    const flow = JSON.parse(graph.flow);
    await this.resetAllStatus(graph);
    let progress = 0;
    for (const [index, id] of flow.entries()) {
      await this.processMiniTask(id, graph);
      progress = ((index + 1) / flow.length) * 100; // 计算当前进度
      this.taskService.updateTaskProgress(task, 2, progress);
    }
    this.taskService.updateTaskProgress(task, 1, progress);
    console.log('所有异步任务完成');
  }

  async executeGraphByTask(id: number, taskId: number) {
    const graph = await this.GraphModel.findOne({
      where: {
        id,
      },
    });
    if (!graph) {
      return {
        succes: false,
        message: '未查询到算法流程',
      };
    }
    let task = await this.taskModel.findOne({
      where: {
        id: taskId,
      },
    })
    const flow = JSON.parse(graph.flow);
    await this.resetAllStatus(graph);
    let progress = 0;
    for (const [index, id] of flow.entries()) {
      await this.processMiniTask(id, graph);
      progress = ((index + 1) / flow.length) * 100; // 计算当前进度
      this.taskService.updateTaskProgress(task, 2, progress);
    }
    this.taskService.updateTaskProgress(task, 1, progress);

    if (graph.name.includes("全国内涝模拟（JSON参数）")) {
      let task_Id = JSON.parse(graph.dynamic)[0].value
      this.pushQanguoSimulationData(task_Id)
    }

    if (graph.name.includes("全国内涝预警(asc参数文件)")) {
      let task_Id = JSON.parse(graph.dynamic)[0].value
      this.pushQanguoWarningData(task_Id)
    }
    console.log('所有异步任务完成');
  }

  async pushQanguoSimulationData(taskId: string) {
    // 定义文件路径
    const filePath = path.join("D:/02ChinaModel/02Project", taskId, "07_ChinaExport", "result.json");
    const url = `${this.renbaoBaseURL}/api/misc/riskcat/imitate/out/receiveTaskData`;

    try {
      // 检查文件是否存在
      if (!fs.existsSync(filePath)) {
        console.error(`文件不存在: ${filePath}`);
        return;
      }

      // 读取 JSON 文件内容
      const fileContent = fs.readFileSync(filePath, 'utf-8');


      const jsonData = JSON.parse(fileContent);

      const originalTimestamp = new Date(jsonData.resultTimestamp);

      // 自定义格式化时间为 YYYY-MM-DD HH:mm:ss
      const formattedTimestamp = `${originalTimestamp.getFullYear()}-${(originalTimestamp.getMonth() + 1).toString().padStart(2, '0')}-${originalTimestamp.getDate().toString().padStart(2, '0')} ${originalTimestamp.getHours().toString().padStart(2, '0')}:${originalTimestamp.getMinutes().toString().padStart(2, '0')}:${originalTimestamp.getSeconds().toString().padStart(2, '0')}`;

      // 修改 jsonData 中的 resultTimestamp
      jsonData.resultTimestamp = formattedTimestamp;
      // 发送 POST 请求
      const response = await axios.post(url, jsonData, {
        headers: {
          'Content-Type': 'application/json',
        }
      });

      console.log("文件内容已成功推送:", response.data);
    } catch (error) {
      console.error("推送文件内容过程中出错:", error);
    }
  }

  async pushQanguoWarningData(taskId: string) {
    // 定义文件路径
    const filePath = path.join("D:/02ChinaModel/03Warning/", taskId, "07_ChinaExport", "result.json");
    const url = `${this.renbaoBaseURL}/api/misc/riskcat/disaster/out/receiveAllWarning`;

    try {
      // 检查文件是否存在
      if (!fs.existsSync(filePath)) {
        console.error(`文件不存在: ${filePath}`);
        return;
      }

      // 读取 JSON 文件内容
      const fileContent = fs.readFileSync(filePath, 'utf-8');


      const jsonData = JSON.parse(fileContent);

      const originalTimestamp = new Date(jsonData.resultTimestamp);

      // 自定义格式化时间为 YYYY-MM-DD HH:mm:ss
      const formattedTimestamp = `${originalTimestamp.getFullYear()}-${(originalTimestamp.getMonth() + 1).toString().padStart(2, '0')}-${originalTimestamp.getDate().toString().padStart(2, '0')} ${originalTimestamp.getHours().toString().padStart(2, '0')}:${originalTimestamp.getMinutes().toString().padStart(2, '0')}:${originalTimestamp.getSeconds().toString().padStart(2, '0')}`;

      // 修改 jsonData 中的 resultTimestamp
      jsonData.resultTimestamp = formattedTimestamp;
      // 发送 POST 请求
      const response = await axios.post(url, [jsonData], {
        headers: {
          'Content-Type': 'application/json',
        }
      });

      console.log("文件内容已成功推送:", response.data);
    } catch (error) {
      console.error("推送文件内容过程中出错:", error);
    }
  }

  async executeGraphByDynamic(id: number, dynamic: any) {
    let result = await this.copyGraph(id, true, dynamic.taskId)
    if (result.data) {
      let copyedGraph = result.data
      let temp = JSON.parse(copyedGraph.dynamic)
      temp.forEach(item => {
        if (item.name == '{history_file}') {
          item.value = dynamic.history_file; // 直接替换 value
        } else if (item.name == '{date_dir}') {
          item.value = dynamic.date_dir; // 直接替换 value
        } else if (item.name == '{date_time}') {
          item.value = dynamic.date_time; // 直接替换 value
        } else if (item.name == '{task_id}') {
          item.value = dynamic.taskId; // 直接替换 value
        }
      });
      copyedGraph.dynamic = JSON.stringify(temp)
      console.log(copyedGraph.dynamic)
      const flow = JSON.parse(copyedGraph.flow);
      let task = await this.taskService.createTaskByGraph(copyedGraph)
      await this.resetAllStatus(copyedGraph);
      let progress = 0;
      for (const [index, id] of flow.entries()) {
        await this.processMiniTask(id, copyedGraph);
        progress = ((index + 1) / flow.length) * 100; // 计算当前进度
        this.taskService.updateTaskProgress(task, 2, progress);
      }
      this.taskService.updateTaskProgress(task, 1, progress);

      const base_url = 'D:/01北京城市内涝模型/5_降水数据下载/01_降水数据'
      const outputFile = `${base_url}/process/${dynamic.date_dir}/${dynamic.date_time}/04_final/${dynamic.date_time}_final.json`
      await this.previewBeijig(outputFile)
      console.log('所有异步任务完成');
    }
  }

  async executeGraphByDynamic2(id: number, dynamic: any) {
    let result = await this.copyGraph(id, true, dynamic.taskId)
    if (result.data) {
      let copyedGraph = result.data
      let temp = JSON.parse(copyedGraph.dynamic)
      temp.forEach(item => {
        if (item.name == '{file_name}') {
          item.value = dynamic.file_name; // 直接替换 value
        } else if (item.name == '{date_dir}') {
          item.value = dynamic.date_dir; // 直接替换 value
        } else if (item.name == '{date_time}') {
          item.value = dynamic.date_time; // 直接替换 value
        } else if (item.name == '{task_id}') {
          item.value = dynamic.taskId; // 直接替换 value
        } else if (item.name == '{forecast_range}') {
          item.value = dynamic.forecastRange; // 直接替换 value
        }
      });
      copyedGraph.dynamic = JSON.stringify(temp)
      console.log(copyedGraph.dynamic)
      const flow = JSON.parse(copyedGraph.flow);
      let task = await this.taskService.createTaskByGraph(copyedGraph)
      await this.resetAllStatus(copyedGraph);
      let progress = 0;
      for (const [index, id] of flow.entries()) {
        await this.processMiniTask(id, copyedGraph);
        progress = ((index + 1) / flow.length) * 100; // 计算当前进度
        this.taskService.updateTaskProgress(task, 2, progress);
      }
      this.taskService.updateTaskProgress(task, 1, progress);
      await this.previewQuanguo(dynamic.output_file)
      console.log('所有异步任务完成');
    }
  }



  async executeGraphByDynamic3(id: number, taskId: any, TM: string) {
    let result = await this.copyGraph(id, true, taskId)
    if (result.data) {
      let copyedGraph = result.data
      let temp = JSON.parse(copyedGraph.dynamic)
      temp.forEach(item => {
        if (item.name == '{taskId}') {
          item.value = taskId;
        }
        if (item.name == '{TM}') {
          item.value = TM;
        }
      });
      copyedGraph.dynamic = JSON.stringify(temp)
      console.log(copyedGraph.dynamic)
      const flow = JSON.parse(copyedGraph.flow);
      let task = await this.taskService.createTaskByGraph(copyedGraph)
      await this.resetAllStatus(copyedGraph);
      let progress = 0;
      for (const [index, id] of flow.entries()) {
        await this.processMiniTask(id, copyedGraph);
        progress = ((index + 1) / flow.length) * 100; // 计算当前进度
        this.taskService.updateTaskProgress(task, 2, progress);
      }
      this.taskService.updateTaskProgress(task, 1, progress);
      this.pushshpFile(taskId)
      // await this.previewQuanguo(dynamic.output_file)
      console.log('所有异步任务完成');
    }
  }


  async executeGraphByDynamic4(id: number, taskId: any) {
    let result = await this.copyGraph(id, true, taskId)
    if (result.data) {
      let copyedGraph = result.data
      let temp = JSON.parse(copyedGraph.dynamic)
      temp.forEach(item => {
        if (item.name == '{task_id}') {
          item.value = taskId;
        }

      });
      copyedGraph.dynamic = JSON.stringify(temp)
      this.GraphModel.save(copyedGraph)
      await this.resetAllStatus(copyedGraph);
      await this.taskService.createAsyncTaskByGraph(copyedGraph)
    }
  }

  async executeGraphByDynamic5(id: number, taskId: any, base_url: string) {
    let result = await this.copyGraph(id, true, taskId)
    if (result.data) {
      let copyedGraph = result.data
      let temp = JSON.parse(copyedGraph.dynamic)
      temp.forEach(item => {
        if (item.name == '{taskId}') {
          item.value = taskId;
        }
        if (item.name == '{base_url}') {
          item.value = base_url;
        }
      });
      copyedGraph.dynamic = JSON.stringify(temp)
      const flow = JSON.parse(copyedGraph.flow);
      let task = await this.taskService.createTaskByGraph(copyedGraph)
      await this.resetAllStatus(copyedGraph);
      let progress = 0;
      for (const [index, id] of flow.entries()) {
        await this.processMiniTask(id, copyedGraph);
        progress = ((index + 1) / flow.length) * 100; // 计算当前进度
        this.taskService.updateTaskProgress(task, 2, progress);
      }
      this.taskService.updateTaskProgress(task, 1, progress);
      console.log('所有异步任务完成');
    }
  }

  async pushshpFile(taskId: string) {
    const sourceDir = path.join("D:\\01北京城市内涝模型\\7_矢量数据转换", taskId, "03_VecAffineCal");
    const targetZipPath = path.join(sourceDir, "..", `${taskId}.zip`);

    // 要打包的文件列表
    const filesToZip = [
      "BJFlood.dbf",
      "BJFlood.shp",
      "BJFlood.shx",
      "BJFlood.prj"
    ];

    // 检查所有文件是否存在
    const missingFiles = filesToZip.filter(file => !fs.existsSync(path.join(sourceDir, file)));
    if (missingFiles.length > 0) {
      console.log(`以下文件缺失: ${missingFiles.join(', ')}`);
      return;
    }

    // 创建输出流
    const output = fs.createWriteStream(targetZipPath);
    const archive = archiver('zip', { zlib: { level: 9 } });

    return new Promise<void>((resolve, reject) => {
      output.on('close', () => {
        console.log(`ZIP 文件已生成: ${targetZipPath}`);
        this.postShpFile(targetZipPath)
        resolve();
      });

      archive.on('error', (err) => {
        console.error("打包过程中出错:", err);
        reject(err);
      });

      archive.pipe(output);

      // 将文件添加到压缩包中
      filesToZip.forEach(file => {
        const filePath = path.join(sourceDir, file);
        archive.file(filePath, { name: file });
      });

      archive.finalize();
    });
  }




  async postShpFile(file_path: string) {
    // const url = "http://106.120.193.138:7777/riskcontrol/riskmap/sendFloodDataFile?clearingFlag=1";
    const url = `${this.renbaoBaseURL}/riskcontrol/riskmap/sendFloodDataFile?clearingFlag=1`;
    try {
      // 创建文件读取流
      const fileStream = fs.createReadStream(file_path);

      // 使用 form-data 创建上传的表单数据
      const formData = new FormData();
      formData.append("file", fileStream, { filename: file_path.split('\\').pop() });

      // 获取 formData 的 headers
      const headers = {
        ...formData.getHeaders() // 确保我们获取的是 form-data 的 headers
      };

      // 使用 axios 发送 POST 请求
      const response = await axios.post(url, formData, { headers });
      console.log("文件上传成功:", response.data);
    } catch (error) {
      console.error("文件上传过程中出错:", error);
    }
  }




  async previewBeijig(outputFile: string) {
    try {
      // 读取文件内容
      const fileContent = fs.readFileSync(outputFile, 'utf-8');

      // 解析 JSON
      const jsonData = JSON.parse(fileContent);
      const originalTimestamp = new Date(jsonData.resultTimestamp);

      // 将时间转换为 UTC（减去 8 小时）
      const offset = -8 * 60 * 60 * 1000; // 东八区的负偏移量
      const adjustedTimestamp = new Date(originalTimestamp.getTime() + offset);

      // 自定义格式化时间为 YYYY-MM-DD HH:mm:ss
      const formattedTimestamp = `${adjustedTimestamp.getFullYear()}-${(adjustedTimestamp.getMonth() + 1).toString().padStart(2, '0')}-${adjustedTimestamp.getDate().toString().padStart(2, '0')} ${adjustedTimestamp.getHours().toString().padStart(2, '0')}:${adjustedTimestamp.getMinutes().toString().padStart(2, '0')}:${adjustedTimestamp.getSeconds().toString().padStart(2, '0')}`;

      jsonData.resultTimestamp = formattedTimestamp;

      // 准备请求地址
      const url = `${this.renbaoBaseURL}/api/misc/riskcat/disaster/out/receiveBeiJingWarning`;

      // 发送 POST 请求
      const response = await axios.post(url, [jsonData], {
        headers: {
          'Content-Type': 'application/json',  // 设置请求头为 JSON 类型
        },
      });
      await fs1.writeFile(outputFile, JSON.stringify([jsonData]));
      // 打印响应结果
      console.log('Response:', response.data);
    } catch (error) {
      // 捕获并处理错误
      console.error('Error:', error.message);
    }
  }

  async previewQuanguo(outputFile: string) {
    try {
      // 读取文件内容
      const fileContent = fs.readFileSync(outputFile, 'utf-8');

      // 解析 JSON
      const jsonData = JSON.parse(fileContent);
      const originalTimestamp = new Date(jsonData.resultTimestamp);

      const taskId = jsonData.taskId

      // 将时间转换为 UTC（减去 8 小时）
      const offset = -8 * 60 * 60 * 1000; // 东八区的负偏移量
      const adjustedTimestamp = new Date(originalTimestamp.getTime() + offset);

      // 自定义格式化时间为 YYYY-MM-DD HH:mm:ss
      const formattedTimestamp = `${adjustedTimestamp.getFullYear()}-${(adjustedTimestamp.getMonth() + 1).toString().padStart(2, '0')}-${adjustedTimestamp.getDate().toString().padStart(2, '0')} ${adjustedTimestamp.getHours().toString().padStart(2, '0')}:${adjustedTimestamp.getMinutes().toString().padStart(2, '0')}:${adjustedTimestamp.getSeconds().toString().padStart(2, '0')}`;

      jsonData.resultTimestamp = formattedTimestamp;
      // 自定义格式化时间为 YYYY-MM-DD HH:mm:ss
      const TM = formattedTimestamp
      const shp_dir = 'BJ_' + jsonData.taskId
      const shpFullDir = 'D:/01北京城市内涝模型/3系统模拟结果/' + shp_dir

      this.taskService.processShpFile(shpFullDir, taskId, TM)
      // 准备请求地址
      const url = `${this.renbaoBaseURL}/api/misc/riskcat/disaster/out/receiveBeiJingWarning`;

      // 发送 POST 请求
      const response = await axios.post(url, [jsonData], {
        headers: {
          'Content-Type': 'application/json',  // 设置请求头为 JSON 类型
        },
      });
      await fs1.writeFile(outputFile, JSON.stringify([jsonData]));
      // 打印响应结果
      console.log('Response:', response.data);
    } catch (error) {
      // 捕获并处理错误
      console.error('Error:', error.message);
    }
  }

  async executeGraphFromNode(id: number, miniTaskId: string): Promise<{
    success: boolean;
    message?: string;
    successCount?: number;
    failedTasks?: string[];
  }> {
    const graph = await this.GraphModel.findOne({
      where: {
        id,
      },
    });
    if (!graph) {
      return {
        success: false,
        message: '未查询到算法流程',
      };
    }
    this.resetAllStatus(graph)
    const flow = JSON.parse(graph.flow);
    const startIndex = flow.indexOf(miniTaskId);
    if (startIndex === -1) {
      return {
        success: false,
        message: '指定的子任务ID不存在',
      };
    }

    let successCount = 0;
    const failedTasks: string[] = [];


    for (let i = startIndex; i < flow.length; i++) {
      const taskId = flow[i];
      try {
        await this.processMiniTask(taskId, graph);
        successCount++;
      } catch (error) {
        console.error(`执行子任务 ${taskId} 时出错:`, error);
        failedTasks.push(taskId);
      }
    }

    return {
      success: true,
      successCount,
      failedTasks: failedTasks.length > 0 ? failedTasks : undefined,
    };
  }

  async invoke(graphId) {
    this.wsApp.clients.forEach(ws => {
      const message = { cmd: 'graph', graphId, action: 'refresh' };
      ws.send(JSON.stringify(message));
    });
  }

  async processMiniTask(id: string, process: Graph) {
    const miniTask = await this.MiniTaskModel.findOne({
      where: {
        id,
      },
    });

    const algorithm = await this.AlgorithmModel.findOne({
      where: { id: miniTask.algorithmId },
    });

    if (!algorithm) {
      return {
        success: false,
        message: '未找到要执行的算法',
      };
    }
    switch (algorithm.executeType) {
      case 1:
        await this.normalExecute(algorithm, miniTask, id, process);
        break;
      case 2:
        await this.tifPublishExecute(algorithm, miniTask, id, process);
        break;
      case 3:
        await this.publishShpFile(algorithm, miniTask, process);
        break;
      case 4:
        await this.bindStyleToLayer(algorithm, miniTask, process);
        break;
      case 5:
        await this.previewResult(miniTask, process); //预览tif+shp
        break;
      case 6:
        await this.pushMPDIResult(miniTask, process);
        break;
      case 7:
        await this.createBatchCatalogue(miniTask, process);
        break;
      case 9:
        await this.generalBatchTask(miniTask, process); //通用批处理算法
        break;
      case 10:
        await this.batchCatalogueByDir(miniTask, process); //批处理目录生成
        break;
      case 11:
        await this.executeMatlabAlgorithm(miniTask, process); //matlab算法执行
        break;
      case 12:
        await this.executePythonAlgorithm(miniTask, process);
        break;
      case 13:
        await this.shpEdit(miniTask, process);
        break;
      case 14:
        await this.executePython3Algorithm(miniTask, process);
        break;
      case 15:
        await this.batchPubilcTif(miniTask, process);
      case 16:
        await this.resultBatchPush(algorithm, miniTask, process); //土含/蒸散发成果批量推送
      case 17:
        await this.irrigationAreaPush(algorithm, miniTask, process); //灌溉面积监测成果推送
      case 18:
        await this.executeLinuxAlgorithm(algorithm, miniTask, process); //灌溉面积监测成果推送
      case 19:
        await this.MultiFactoraPush(algorithm, miniTask, process); //多要素联合模拟成果推送
      case 20:
        await this.AnalysisWaterPush(algorithm, miniTask, process); //耗水过程解析成果推送
      case 21:
        await this.executeUploadAlgorithm(algorithm, miniTask, process);
      case 22:
        await this.fetchToken(algorithm, miniTask, process);
      default:
        break;
    }
  }

  replace(json: any, filter: any[]) {
    if (filter && filter.length > 0) {
      for (const replacement of filter) {
        const { name, value } = replacement;
        for (const key in json) {
          if (typeof json[key] === 'string') {
            json[key] = json[key].replace(new RegExp(name, 'g'), value);
          }
        }
      }
    }
    return json;
  }


  async normalExecute(
    algorithm: Algorithm,
    miniTask: MiniTask,
    id: string,
    process: Graph
  ) {
    const exePath = algorithm.application;
    const parameters = JSON.parse(miniTask.runTimeParams);
    const parametersParsed = this.convertJsonArrayToObject(parameters);
    const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
    console.log(jsonParameterFiltered)
    if (jsonParameterFiltered.outputFile) {
      const outputFile = jsonParameterFiltered.outputFile;
      const outputDirPath = path.dirname(outputFile);
      // 检查目录是否存在
      if (!fs.existsSync(outputDirPath)) {
        // 创建目录
        fs.mkdirSync(outputDirPath, { recursive: true });
      }
    }

    if (jsonParameterFiltered.jsonFile) {
      const jsonFile = jsonParameterFiltered.jsonFile;
      const jsonFileDirPath = path.dirname(jsonFile);
      // 检查目录是否存在
      if (!fs.existsSync(jsonFileDirPath)) {
        // 创建目录
        fs.mkdirSync(jsonFileDirPath, { recursive: true });
      }
    }
    // 使用child_process.spawn执行exe程序
    this.changeGraphStatus(id, process, 'running');
    return new Promise((resolve, reject) => {
      const child = childProcess.spawn(exePath, [JSON.stringify(jsonParameterFiltered)]);
      let logOutput = ''; // 用于保存日志信息
      // 监听子进程的标准输出
      child.stdout.on('data', data => {
        logOutput += data.toString('utf-8');
        let log = data.toString('utf-8');
        console.log(log)
      });
      // 监听子进程的标准错误输出
      child.stderr.on('data', data => {
        logOutput += data.toString('utf-8');
        console.log(data.toString('utf-8'));
        // this.changeGraphStatus(id, process, 'failed');
      });

      console.log(exePath + " " + JSON.stringify(jsonParameterFiltered))

      child.on('exit', code => {
        console.log('算法执行完成');
        if (miniTask.pause == false) {
          this.changeGraphStatus(id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('算法执行完成');
            this.changeGraphStatus(id, process, 'success');
            resolve('success');
          });
        }
      });


    });
  }


  async tifPublishExecute(
    algorithm: Algorithm,
    miniTask: MiniTask,
    id: string,
    process: Graph
  ) {
    const parameters = JSON.parse(miniTask.runTimeParams);
    const parametersParsed = this.convertJsonArrayToObject(parameters);
    const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
    const workspace = 'result';
    this.changeGraphStatus(id, process, 'running');
    const tifFilePath = jsonParameterFiltered.image_path;
    let { name } = path.parse(tifFilePath);
    const layerName = name;
    // GeoServer 的认证信息，如果不需要认证，可以将这部分省略
    const username = 'admin';
    const password = 'geoserver';
    const restUrl = `${algorithm.application}/geoserver/rest/workspaces/${workspace}/coveragestores/${layerName}/file.geotiff`;
    // 构造认证信息
    const auth = `${username}:${password}`;
    const url = `${algorithm.application}/geoserver/rest/workspaces/${workspace}/datastores/${layerName}`;
    try {
      const response = await axios.delete(url, {
        // 添加请求头，例如授权信息等
        headers: {
          Authorization: `Basic ${Buffer.from(auth).toString('base64')}`,
        },
      });
      console.log('删除数据存储成功');
    } catch (error) {
      console.error('删除数据存储失败');
    }
    return new Promise(async resolve => {
      setTimeout(async () => {
        const fileData = await fs.promises.readFile(tifFilePath);
        const response = await axios.put(restUrl, fileData, {
          headers: {
            'Content-Type': 'image/tiff',
            Authorization: `Basic ${Buffer.from(auth).toString('base64')}`,
          },
        });
        if (response) {
          if (miniTask.pause == false) {
            this.changeGraphStatus(id, process, 'success');
            resolve('success');
          } else {
            this.changeGraphStatus(id, process, 'pause');
            this.promiseService.createPromise(miniTask.id).then(() => {
              console.log('算法执行完成');
              this.changeGraphStatus(id, process, 'success');
              resolve('success');
            });
          }
        }
      }, 4000);
    });
  }

  async publishShpFile(
    algorithm: Algorithm,
    miniTask: MiniTask,
    process: Graph
  ) {
    const parameters = JSON.parse(miniTask.runTimeParams);
    let parsedParams = this.convertJsonArrayToObject(parameters);
    const jsonParameterFiltered = this.replace(parsedParams, JSON.parse(process.dynamic))
    console.log(jsonParameterFiltered);
    const shpPath = jsonParameterFiltered.shp_path;
    let { name, dir } = path.parse(shpPath);
    const shpZipFile = `${dir}/${name}_shp.zip`;
    this.changeGraphStatus(miniTask.id, process, 'running');
    return await this.compressShpToZip(
      shpPath,
      shpZipFile,
      name,
      miniTask,
      algorithm,
      process
    );
  }

  async compressShpToZip(
    shpFilePath: string,
    outputZipPath: string,
    shpName: string,
    miniTask: MiniTask,
    algorithm: Algorithm,
    process: Graph
  ) {
    const self = this;
    return new Promise(async (resolve, reject) => {
      // 创建一个输出流到指定的 ZIP 文件
      const output = fs.createWriteStream(outputZipPath);
      const archive = archiver('zip', {
        zlib: { level: 9 }, // 设置压缩级别
      });

      // 监听错误事件
      output.on('error', function (err) {
        reject(err);
      });

      // 监听关闭事件
      output.on('close', async function () {
        console.log(archive.pointer() + ' total bytes');
        let result = await self.publishShpToGeoServer(
          outputZipPath,
          shpName,
          miniTask,
          algorithm,
          process
        );
        resolve(result);
      });

      // 绑定输出流到压缩程序
      archive.pipe(output);

      // 获取文件名
      const shpFileName = shpFilePath.split('/').pop().replace('.shp', '');
      // 将与 .shp 文件同名的文件（除了 .zip 文件）添加到压缩程序
      const shpFileDir = path.dirname(shpFilePath);
      return await fs.readdir(shpFileDir, async (err, files) => {
        if (err) {
          reject(err);
        } else {
          files.forEach(file => {
            if (
              (file.startsWith(shpFileName) && file.endsWith('.shx')) ||
              file.endsWith('.dbf') ||
              file.endsWith('.shp') ||
              file.endsWith('.prj')
            ) {
              console.log(file);
              const filePath = path.join(shpFileDir, file);
              const pathObj = path.parse(file);
              const newFileName = pathObj.name + '_shp' + pathObj.ext;
              archive.file(filePath, { name: newFileName });
            }
          });
          // 完成压缩
          await archive.finalize();
        }
      });
    });
  }

  private async publishShpToGeoServer(
    shpFilePath: string,
    shpName: string,
    miniTask: MiniTask,
    algorithm: Algorithm,
    process: Graph
  ) {
    const workspace = 'result';
    const layerName = shpName + '_shp';

    // GeoServer 的认证信息，如果不需要认证，可以将这部分省略
    const username = 'admin';
    const password = 'geoserver';

    const restUrl = `${algorithm.application}/geoserver/rest/workspaces/${workspace}/datastores/${layerName}/file.shp`;

    // 构造认证信息
    const auth = `${username}:${password}`;

    return new Promise(async resolve => {
      const fileData = await fs.promises.readFile(shpFilePath);

      const response = await axios.put(restUrl, fileData, {
        headers: {
          'Content-Type': 'application/zip',
          Authorization: `Basic ${Buffer.from(auth).toString('base64')}`,
        },
      });

      console.log('Shapefile 成功发布到 GeoServer!');
      await setTimeout(() => {
        if (miniTask.pause == false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('算法执行完成');
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          });
        }
      }, 2000);
    });
  }

  async bindStyleToLayer(
    algorithm: Algorithm,
    miniTask: MiniTask,
    process: Graph
  ) {
    return new Promise(async (resolve, reject) => {
      try {
        this.changeGraphStatus(miniTask.id, process, 'running');
        // GeoServer 的认证信息，如果不需要认证，可以将这部分省略
        const username = 'admin';
        const password = 'geoserver';
        // 构造认证信息
        const auth = `${username}:${password}`;
        const geoserverUrl = algorithm.application; // GeoServer 的 URL
        const workspace = 'result'; // 工作区名称
        const parameters = JSON.parse(miniTask.runTimeParams);
        let parsedParams = this.convertJsonArrayToObject(parameters);
        const jsonParameterFiltered = this.replace(parsedParams, JSON.parse(process.dynamic))
        console.log(jsonParameterFiltered);
        const layerName = jsonParameterFiltered.layer_name;
        const styleName = jsonParameterFiltered.style_name;
        const data = {
          layer: {
            defaultStyle: {
              name: styleName,
            },
          },
        };
        // 发送 PUT 请求将样式应用到图层
        let response = await axios.put(
          `${geoserverUrl}/geoserver/rest/layers/${workspace}:${layerName}`,
          data,
          {
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Basic ${Buffer.from(auth).toString('base64')}`,
            },
          }
        );
        if (response.status == 200) {
          if (miniTask.pause == false) {
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          } else {
            this.changeGraphStatus(miniTask.id, process, 'pause');
            this.promiseService.createPromise(miniTask.id).then(() => {
              console.log('算法执行完成');
              this.changeGraphStatus(miniTask.id, process, 'success');
              resolve('success');
            });
          }
        } else {
          this.changeGraphStatus(miniTask.id, process, 'error');
          resolve('success');
        }
      } catch (error) {
        this.changeGraphStatus(miniTask.id, process, 'error');
        console.error('图层样式绑定失败', error);
        reject(error);
      }
    });
  }

  async previewResult(miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise((resolve, reject) => {
      setTimeout(async () => {
        this.changeGraphStatus(miniTask.id, process, 'success');
        if (miniTask.pause == false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('算法执行完成');
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          });
        }
      }, 4000);
    });
  }

  @InjectEntityModel(M1Product)
  M1ProductModel: Repository<M1Product>;

  async pushMPDIResult(miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise((resolve, reject) => {
      setTimeout(async () => {
        const parameters = JSON.parse(miniTask.runTimeParams);
        const parametersParsed = this.convertJsonArrayToObject(parameters);
        const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
        const m1Product = new M1Product();
        m1Product.box = JSON.stringify([jsonParameterFiltered.minX, jsonParameterFiltered.minY, jsonParameterFiltered.maxX, jsonParameterFiltered.maxY])
        m1Product.productName = jsonParameterFiltered.origin_img
        m1Product.step1 = jsonParameterFiltered.origin_img
        m1Product.step2 = jsonParameterFiltered.after_img
        m1Product.step3 = jsonParameterFiltered.MPDI_product
        m1Product.step4 = jsonParameterFiltered.soil_water
        m1Product.step5 = jsonParameterFiltered.calc
        m1Product.satelliteType = jsonParameterFiltered.satelliteType
        m1Product.produceDate = jsonParameterFiltered.produceDate
        this.M1ProductModel.save(m1Product)
        if (miniTask.pause == false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('算法执行完成');
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          });
        }
      }, 4000);
    });
  }

  async createBatchCatalogue(miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise(async (resolve, reject) => {
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);
      const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
      try {
        setTimeout(async () => {
          const { outputFile } = jsonParameterFiltered;
          console.log(outputFile)
          // 将对象转换为 JSON 字符串
          const jsonContent = JSON.stringify(jsonParameterFiltered, null, 2);
          // 确保目录存在，如果不存在则创建
          const dir = path.dirname(outputFile);
          if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
          }
          // 将 JSON 字符串写入指定路径的文件
          await fs.promises.writeFile(outputFile, jsonContent, 'utf8');
          if (miniTask.pause == false) {
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          } else {
            this.changeGraphStatus(miniTask.id, process, 'pause');
            this.promiseService.createPromise(miniTask.id).then(() => {
              console.log('算法执行完成');
              this.changeGraphStatus(miniTask.id, process, 'success');
              resolve('success');
            });
          }
        }, 3000)
        // 返回成功消息和 JSON 文件路径
      } catch (error) {
        this.changeGraphStatus(miniTask.id, process, 'error');
        console.error('Error:', error);
      }
    });
  }

  async generalBatchTask(miniTask: MiniTask, process: Graph, maxConcurrent = 2) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise(async (resolve, reject) => {
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);
      const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic));
      const outputDir = jsonParameterFiltered.outputDir;
      const outputSuffix = jsonParameterFiltered.outputSuffix;
      const outputType = jsonParameterFiltered.outputType;
      const algorithmId = jsonParameterFiltered.algorithm;
      const runtimeParams = jsonParameterFiltered.runtimeParams;
      const runtimeParamsParsed = this.convertJsonArrayToObject(runtimeParams);
      const algorithm = await this.AlgorithmModel.findOne({
        where: {
          id: algorithmId,
        },
      });

      fs.readFile(jsonParameterFiltered.inputFile, 'utf8', async (err, data) => {
        if (err) {
          console.error('Error reading input file:', err);
          return reject(err);
        }
        const jsonContent = JSON.parse(data);
        const files = jsonContent.files;

        let activeTasks = 0;
        let currentIndex = 0;

        const processNext = async () => {
          // 当所有任务完成且没有活动任务时，标记为成功
          if (currentIndex >= files.length && activeTasks === 0) {
            console.log('算法全部执行完成');
            this.updateGraphStatus(miniTask, process, 'success', resolve);
            return;
          }

          // 启动新任务直到达到最大并发数
          while (activeTasks < miniTask.Parallel && currentIndex < files.length) {
            const file = files[currentIndex++];
            activeTasks++;

            this.processFile(file, runtimeParamsParsed, algorithm, outputDir, outputSuffix, outputType, process)
              .then(() => {
                activeTasks--;
                processNext(); // 完成一个任务后继续下一个
              })
              .catch((error) => {
                console.error(`文件 ${file} 处理出错:`, error);
                this.changeGraphStatus(miniTask.id, process, 'error');
                reject(error);
              });
          }
        };

        processNext(); // 开始处理任务
      });
    });
  }

  // 定义 processFile 方法
  async processFile(file: string, runtimeParamsParsed: any, algorithm: any, outputDir: string, outputSuffix: string, outputType: string, process: Graph) {
    return new Promise((resolve, reject) => {
      const { name } = path.parse(file);
      const exePath = algorithm.application;
      runtimeParamsParsed.inputFile = file;
      runtimeParamsParsed.outputFile = `${outputDir}/${name}${outputSuffix}${outputType}`;
      const runtimeParamsParsedFiltered = this.replace(runtimeParamsParsed, JSON.parse(process.dynamic));
      const outputFile = runtimeParamsParsedFiltered.outputFile;
      const outputDirPath = path.dirname(outputFile);

      // 检查并创建目录
      if (!fs.existsSync(outputDirPath)) {
        fs.mkdirSync(outputDirPath, { recursive: true });
      }

      // 执行算法
      if (algorithm.executeType === 1) {
        const child = childProcess.spawn(exePath, [JSON.stringify(runtimeParamsParsedFiltered)]);
        console.log(exePath + ' ' + [JSON.stringify(runtimeParamsParsedFiltered)])

        let logOutput = '';

        child.stdout.on('data', data => {
          logOutput += data.toString('utf-8');
          console.log(data.toString('utf-8'));
        });
        child.stderr.on('data', data => {
          logOutput += data.toString('utf-8');
          console.error(data.toString('utf-8'));
        });
        child.on('error', (err) => {
          console.error('Failed to start subprocess.');
          reject(err);
        });
        child.on('exit', () => {
          console.log('算法执行完成');
          resolve('success');
        });
      } else {
        const pythonProcess = childProcess.spawn(this.ArcGISPythonURL, [exePath, JSON.stringify(runtimeParamsParsedFiltered)]);
        pythonProcess.stdout.on('data', (data) => {
          console.log(`stdout: ${data}`);
        });

        pythonProcess.stderr.on('data', (data) => {
          console.error(`stderr: ${data}`);
        });

        pythonProcess.on('close', () => {
          console.log('子进程退出');
          resolve('success');
        });
      }
    });
  }
  // 更新图状态的辅助方法
  updateGraphStatus(miniTask: MiniTask, process: Graph, status: string, resolve: Function) {
    this.changeGraphStatus(miniTask.id, process, status);
    if (status === 'success') {
      if (!miniTask.pause) {
        resolve('success');
      } else {
        this.changeGraphStatus(miniTask.id, process, 'pause');
        this.promiseService.createPromise(miniTask.id).then(() => {
          console.log('算法执行完成');
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        });
      }
    }
  }

  getJsonPathFromTif(tifFilePath) {
    const dir = path.dirname(tifFilePath);
    const baseName = path.basename(tifFilePath, path.extname(tifFilePath));
    return path.join(dir, baseName + '.json');
  }

  setBoxFromJsonFile(jsonFilePath) {
    const jsonStr = fs.readFileSync(jsonFilePath, 'utf-8');
    const jsonObj = JSON.parse(jsonStr);
    return jsonObj;
  }


  async resultBatchPush(algorithm: Algorithm, miniTask: MiniTask, process: Graph) {
    const exePath = algorithm.application;
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise(async (resolve, reject) => {
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);

      const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
      fs.readFile(jsonParameterFiltered.inputFile, 'utf8', async (err, data) => {
        if (err) {
          console.error('Error reading input file:', err);
          return reject(err);
        }
        const jsonContent = JSON.parse(data);
        const files = jsonContent.files;
        const promises = files.map((file, index) => {
          return new Promise((resolve, reject) => {
            let params = {
              AlgoName: 'RSSpaceExtent',
              inputFile: file,
              outputFile: this.getJsonPathFromTif(file),
            };
            const child = childProcess.spawn(exePath, [JSON.stringify(params)]);
            child.on('exit', () => {
              const box = this.setBoxFromJsonFile(this.getJsonPathFromTif(file))
              const { name } = path.parse(file);
              const soilEtResult = new SoilEtResult();
              soilEtResult.fileName = name
              soilEtResult.monitorDate = jsonParameterFiltered.monitorDate
              soilEtResult.irrigationArea = jsonParameterFiltered.irrigationArea
              soilEtResult.resultType = jsonParameterFiltered.resultType
              soilEtResult.box = JSON.stringify([box.minX, box.minY, box.maxX, box.maxY])
              soilEtResult.filePath = file
              const result = this.SoilEtResultModel.save(soilEtResult)
              if (result) {
                console.log(`成果${index}推送完成`);
                resolve('success');
              }
            });
          });
        });
        try {
          await Promise.all(promises);
          console.log(`算法全部执行完成`);
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
          resolve(4000);
        } catch (error) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          console.log(error)
          reject(error);
        }
      });

    });
  }

  async irrigationAreaPush(algorithm: Algorithm, miniTask: MiniTask, process: Graph) {
    const exePath = algorithm.application;
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise(async (resolve, reject) => {
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);
      const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
      console.log(jsonParameterFiltered.inputFile)
      const inputFile = jsonParameterFiltered.inputFile;
      let params = {
        AlgoName: 'RSSpaceExtent',
        inputFile: inputFile,
        outputFile: this.getJsonPathFromTif(inputFile),
      };
      const child = childProcess.spawn(exePath, [JSON.stringify(params)]);
      child.on('exit', () => {
        const box = this.setBoxFromJsonFile(this.getJsonPathFromTif(inputFile))
        const { name } = path.parse(inputFile);
        const soilEtResult = new SoilEtResult();
        soilEtResult.fileName = name
        soilEtResult.monitorDate = jsonParameterFiltered.monitorDate
        soilEtResult.irrigationArea = jsonParameterFiltered.irrigationArea
        soilEtResult.resultType = jsonParameterFiltered.resultType
        soilEtResult.box = JSON.stringify([box.minX, box.minY, box.maxX, box.maxY])
        soilEtResult.filePath = inputFile
        soilEtResult.csvFileId = "d7a76a4e-eefe-4b8d-bfa5-c22c6c8a5078"
        const result = this.SoilEtResultModel.save(soilEtResult)
        if (result) {
          console.log(`成果推送完成`);
          resolve('success');
        }
      });
      try {
        console.log(`算法全部执行完成`);
        this.changeGraphStatus(miniTask.id, process, 'success');
        resolve('success');
        resolve(4000);
      } catch (error) {
        this.changeGraphStatus(miniTask.id, process, 'success');
        console.log(error)
        reject(error);
      }

    });
  }


  async AnalysisWaterPush(algorithm: Algorithm, miniTask: MiniTask, process: Graph) {

    const exePath = algorithm.application;
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise(async (resolve, reject) => {
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);
      const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
      console.log(jsonParameterFiltered.inputFile)
      const inputFile = jsonParameterFiltered.inputFile;
      let params = {
        AlgoName: 'RSSpaceExtent',
        inputFile: inputFile,
        outputFile: this.getJsonPathFromTif(inputFile),
      };
      const child = childProcess.spawn(exePath, [JSON.stringify(params)]);
      child.on('exit', () => {
        const box = this.setBoxFromJsonFile(this.getJsonPathFromTif(inputFile))
        const { name } = path.parse(inputFile);
        const soilEtResult = new SoilEtResult();
        soilEtResult.fileName = name
        soilEtResult.monitorDate = jsonParameterFiltered.monitorDate
        soilEtResult.irrigationArea = jsonParameterFiltered.irrigationArea
        soilEtResult.resultType = jsonParameterFiltered.resultType
        soilEtResult.box = JSON.stringify([box.minX, box.minY, box.maxX, box.maxY])
        soilEtResult.filePath = inputFile
        soilEtResult.etType = jsonParameterFiltered.etType
        const result = this.SoilEtResultModel.save(soilEtResult)
        if (result) {
          console.log(`成果推送完成`);
          resolve('success');
        }
      });
      try {
        console.log(`算法全部执行完成`);
        this.changeGraphStatus(miniTask.id, process, 'success');
        resolve('success');
        resolve(4000);
      } catch (error) {
        this.changeGraphStatus(miniTask.id, process, 'success');
        console.log(error)
        reject(error);
      }

    });
  }

  async fetchToken(algorithm: Algorithm, miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise((resolve, reject) => {
      setTimeout(async () => {
        const parameters = JSON.parse(miniTask.runTimeParams);
        const parametersParsed = this.convertJsonArrayToObject(parameters);
        const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
        const jsonData = JSON.stringify({
          account: jsonParameterFiltered.account,
          password: jsonParameterFiltered.password,
          appKey: RsaEncryptUtil.getCurrentISOTimestamp(),
          timestamp: jsonParameterFiltered.timestamp
        })
        const encrypted2 = RsaEncryptUtil.encryptJson(jsonData);
        const params = {
          encryptedData: encrypted2,
        };
        try {
          const response = await fetch(algorithm.application, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(params)  // 参数放在请求体中
          });
          if (response.ok) {
            console.log(`算法执行完成`);
            const data = (await response.json()).data;
            console.log(data)
            let temp = JSON.parse(process.dynamic)
            temp.forEach(item => {
              if (item.name == '{token}') {
                item.value = data;
              }
            });
            process.dynamic = JSON.stringify(temp)
            await this.GraphModel.save(process);
            this.changeGraphStatus(miniTask.id, process, 'success');
            await setTimeout(() => {
              this.changeGraphStatus(miniTask.id, process, 'success');
              resolve('success');
              resolve(4000);
            }, 60000)
          } else {
            console.error(`算法执行失败:`, response.status);
            this.changeGraphStatus(miniTask.id, process, 'success');
            reject(new Error(`HTTP ${response.status}`));
          }
        } catch (error) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        }
        if (miniTask.pause == false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('算法执行完成');
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          });
        }
      }, 4000);
    });
  }

  async MultiFactoraPush(algorithm: Algorithm, miniTask: MiniTask, process: Graph) {
    const exePath = algorithm.application;
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise(async (resolve, reject) => {
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);
      const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
      console.log(jsonParameterFiltered.inputFile)
      const inputFile = jsonParameterFiltered.inputFile;
      let params = {
        AlgoName: 'RSSpaceExtent',
        inputFile: inputFile,
        outputFile: this.getJsonPathFromTif(inputFile),
      };
      const child = childProcess.spawn(exePath, [JSON.stringify(params)]);
      child.on('exit', () => {
        const box = this.setBoxFromJsonFile(this.getJsonPathFromTif(inputFile))
        const { name } = path.parse(inputFile);
        const soilEtResult = new SoilEtResult();
        soilEtResult.fileName = name
        soilEtResult.monitorDate = jsonParameterFiltered.monitorDate
        soilEtResult.irrigationArea = jsonParameterFiltered.irrigationArea
        soilEtResult.resultType = jsonParameterFiltered.resultType
        soilEtResult.box = JSON.stringify([box.minX, box.minY, box.maxX, box.maxY])
        soilEtResult.filePath = inputFile
        console.log(jsonParameterFiltered.soilWaterType)
        soilEtResult.soilWaterType = jsonParameterFiltered.soilWaterType
        const result = this.SoilEtResultModel.save(soilEtResult)
        if (result) {
          console.log(`成果推送完成`);
          resolve('success');
        }
      });
      try {
        console.log(`算法全部执行完成`);
        this.changeGraphStatus(miniTask.id, process, 'success');
        resolve('success');
        resolve(4000);
      } catch (error) {
        this.changeGraphStatus(miniTask.id, process, 'success');
        console.log(error)
        reject(error);
      }

    });
  }



  async executeLinuxAlgorithm(algorithm: Algorithm, miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise((resolve, reject) => {
      setTimeout(async () => {
        const parameters = JSON.parse(miniTask.runTimeParams);
        const parametersParsed = this.convertJsonArrayToObject(parameters);
        const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
        try {
          const response = await fetch(algorithm.application, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(parameters)  // 参数放在请求体中
          });
          if (response.ok) {
            console.log(`算法执行完成`);
            this.changeGraphStatus(miniTask.id, process, 'success');
            await setTimeout(() => {
              this.changeGraphStatus(miniTask.id, process, 'success');
              resolve('success');
              resolve(4000);
            }, 60000)
          } else {
            console.error(`算法执行失败:`, response.status);
            this.changeGraphStatus(miniTask.id, process, 'success');
            reject(new Error(`HTTP ${response.status}`));
          }
        } catch (error) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
          reject(error);
        }
        if (miniTask.pause == false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('算法执行完成');
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          });
        }
      }, 4000);
    });
  }


  async executeUploadAlgorithm(algorithm: Algorithm, miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');

    return new Promise((resolve, reject) => {
      setTimeout(async () => {
        const parameters = JSON.parse(miniTask.runTimeParams);
        const parametersParsed = this.convertJsonArrayToObject(parameters);
        const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic));
        console.log(jsonParameterFiltered);

        try {
          // 创建form-data实例
          const formData = new FormData();

          // 添加文件到form-data
          const zipFilePath = jsonParameterFiltered.zipFile;
          const fileStream = fs.createReadStream(zipFilePath);
          const fileName = path.basename(zipFilePath);

          formData.append('file', fileStream, {
            filename: fileName,
            contentType: 'application/zip'
          });

          // 如果需要传递其他参数，可以添加到form-data中
          // formData.append('otherParam', 'value');

          const response = await fetch(algorithm.application, {
            method: 'POST',
            headers: {
              // 'Authorization': `Bearer ${jsonParameterFiltered.token}`, // token放在header中
              'token': jsonParameterFiltered.token,
              ...formData.getHeaders() // 获取form-data的headers，包括boundary
            },
            body: formData
          });

          if (response.ok) {
            console.log(`文件上传完成`);
            this.changeGraphStatus(miniTask.id, process, 'success');
            console.log( await response.json())
            await new Promise(resolve => setTimeout(resolve, 60000)); // 修复setTimeout用法
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          } else {
            console.error(`文件上传失败:`, response.status);
            const errorText = await response.text();
            console.error('错误详情:', errorText);
            this.changeGraphStatus(miniTask.id, process, 'failed');
            reject(new Error(`HTTP ${response.status}: ${errorText}`));
          }
        } catch (error) {
          console.error('上传过程中发生错误:', error);
          this.changeGraphStatus(miniTask.id, process, 'failed');
          reject(error);
        }

        // 处理暂停逻辑
        if (miniTask.pause == false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('文件上传完成');
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          });
        }
      }, 4000);
    });
  }



  async batchCatalogueByDir(miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise((resolve, reject) => {
      setTimeout(async () => {
        const parameters = JSON.parse(miniTask.runTimeParams);
        const parametersParsed = this.convertJsonArrayToObject(parameters);
        const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
        console.log(jsonParameterFiltered)
        let folderPath = jsonParameterFiltered.Dir
        let type = [jsonParameterFiltered.fileType]
        // 检查文件夹路径是否存在
        if (!fs.existsSync(folderPath)) {
          return { message: '文件夹不存在' };
        }
        // 读取文件夹中的文件列表
        const files = await fs.promises.readdir(folderPath);
        const fileList: any[] = [];
        for (const file of files) {
          const filePath = path.join(folderPath, file).replace(/\\/g, '/');
          const stats = await fs.promises.stat(filePath);
          // 如果文件不是文件夹，并且文件扩展名在指定类型中，则将其添加到文件列表中
          if (!stats.isDirectory()) {
            if (type.length > 0) {
              type.indexOf(path.extname(file)) !== -1 && fileList.push(filePath);
            }
          }
        }
        let outputFile = jsonParameterFiltered.outputFile
        const outputDirPath = path.dirname(outputFile);
        // 检查目录是否存在
        if (!fs.existsSync(outputDirPath)) {
          // 创建目录
          fs.mkdirSync(outputDirPath, { recursive: true });
        }
        // 返回文件列表
        let Content = { files: fileList, outputFile };

        // 将对象转换为 JSON 字符串
        const jsonContent = JSON.stringify(Content, null, 2);

        // 确保目录存在，如果不存在则创建
        const dir = path.dirname(outputFile);
        if (!fs.existsSync(dir)) {
          fs.mkdirSync(dir, { recursive: true });
        }
        // 将 JSON 字符串写入指定路径的文件
        await fs.promises.writeFile(outputFile, jsonContent, 'utf8');
        if (miniTask.pause == false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('算法执行完成');
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          });
        }
      }, 4000);
    });
  }

  async executeMatlabAlgorithm(miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    const algorithm = await this.AlgorithmModel.findOne({
      where: {
        id: miniTask.algorithmId,
      },
    });
    return new Promise((resolve, reject) => {
      const exePath = algorithm.application;
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);
      const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic))
      jsonParameterFiltered.task_id = (miniTask.id).toString()
      const now = new Date();
      const timestamp = `${now.getHours()}-${now.getMinutes()}-${now.getSeconds()}`;
      const fileName = `runtime_params_${miniTask.id}_${timestamp}.json`;
      const filePath = path.join(this.matlabRuntimeParamPath, fileName);
      fs.writeFile(filePath, JSON.stringify(jsonParameterFiltered, null, 2), (err) => {
        if (err) {
          reject(err);
          return;
        }

        const jsonFilePath = filePath;
        const addpath = path.dirname(exePath);
        const mainFunction = path.basename(exePath, '.m');
        const matlabCommand = `jsonFilePath = '${jsonFilePath}'; addpath('${addpath}'); ${mainFunction}(jsonFilePath); exit`;
        const child = childProcess.spawn(this.matlabExePath, ['-nodisplay', '-nosplash', '-nodesktop', '-r', matlabCommand]);
        let logOutput = ''; // 用于保存日志信息

        // 监听子进程的标准输出
        child.stdout.on('data', data => {
          logOutput += data.toString('utf-8');
          let log = data.toString('utf-8');
          console.log(log); // 输出日志到控制台
        });

        // 监听子进程的标准错误输出
        child.stderr.on('data', data => {
          logOutput += data.toString('utf-8');
          console.error(data.toString('utf-8'));
        });

        // 监听子进程的退出事件
        child.on('exit', async code => {
        });
        this.promiseService.createPromise((miniTask.id).toString()).then(() => {
          console.log('算法执行完成');
          if (miniTask.pause == false) {
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          } else {
            this.changeGraphStatus(miniTask.id, process, 'pause');
            this.promiseService.createPromise(miniTask.id).then(() => {
              console.log('算法执行完成');
              this.changeGraphStatus(miniTask.id, process, 'success');
              resolve('success');
            });
          }
          fs.unlink(jsonFilePath, (err) => { });
        });

        // 监听子进程的错误事件
        child.on('error', err => {
          console.error('子进程错误:', err);
          reject(err);
        });
      });
    });
  }

  async executePythonAlgorithm(miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    const algorithm = await this.AlgorithmModel.findOne({
      where: {
        id: miniTask.algorithmId,
      },
    });
    return new Promise((resolve, reject) => {
      const exePath = algorithm.application;
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);
      const { spawn } = require('child_process');
      console.log(JSON.stringify(parametersParsed))
      console.log(this.ArcGISPythonURL)
      const pythonProcess = spawn(this.ArcGISPythonURL, [exePath, JSON.stringify(parametersParsed)]);
      pythonProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
      });

      pythonProcess.stderr.on('data', (data) => {
        console.error(`stderr: ${data}`);
      });

      pythonProcess.on('close', async (code) => {
        console.log(`child process exited with code ${code}`);
        this.changeGraphStatus(miniTask.id, process, 'success');
        resolve('success');
      });
    });
  }
  async executePython3Algorithm(miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    const algorithm = await this.AlgorithmModel.findOne({
      where: {
        id: miniTask.algorithmId,
      },
    });
    return new Promise(async (resolve, reject) => {
      const exePath = algorithm.application;
      const parameters = JSON.parse(miniTask.runTimeParams);
      const parametersParsed = this.convertJsonArrayToObject(parameters);
      const { spawn } = require('child_process');
      // 创建 temp 文件夹路径
      const tempDir = path.join("C:/zyjx", 'temp');
      // 确保 temp 文件夹存在
      if (!fs.existsSync(tempDir)) {
        fs.mkdirSync(tempDir, { recursive: true });
      }
      // 创建带时间戳的临时文件名
      const timestamp = new Date().toISOString().replace(/:/g, '-');
      const tempFilePath = path.join(tempDir, `temp_params_${timestamp}.json`);
      fs.writeFileSync(tempFilePath, JSON.stringify(parametersParsed));
      console.log(`Parameters written to ${tempFilePath}`);
      console.log(`Python URL: ${this.PythonURL}`);
      console.log(`Executable Path: ${exePath}`);
      const pythonProcess = await spawn(this.PythonURL, [exePath, tempFilePath]);
      pythonProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
      });

      pythonProcess.stderr.on('data', (data) => {
        console.error(`stderr: ${data}`);
      });

      pythonProcess.on('close', async (code) => {
        console.log(`child process exited with code ${code}`);
        // 删除临时文件
        fs.unlink(tempFilePath, (err) => {
          if (err) {
            console.error(`Failed to delete temp file: ${err}`);
          }
        });
        this.changeGraphStatus(miniTask.id, process, 'success');
        resolve('success');
      });
    });
  }

  async batchPubilcTif(miniTask, process) {
    const agent = new http.Agent({
      keepAlive: true,
      maxSockets: Infinity,
      highWaterMark: 1024 * 1024 * 10, // 设置每次上传的缓冲区为10MB
    });

    const parameters = JSON.parse(miniTask.runTimeParams);
    const parametersParsed = this.convertJsonArrayToObject(parameters);
    const jsonParameterFiltered = this.replace(parametersParsed, JSON.parse(process.dynamic));
    const inputFile = jsonParameterFiltered.inputFile;
    const laye_pre = jsonParameterFiltered.laye_pre;
    const layer_suffix = jsonParameterFiltered.layer_suffix;

    this.changeGraphStatus(miniTask.id, process, 'running');

    return new Promise(async (resolve, reject) => {
      try {
        // 读取输入文件，这个文件包含了 TIFF 文件路径
        const data = await fs.promises.readFile(inputFile, 'utf8');
        const jsonContent = JSON.parse(data);
        const files = jsonContent.files; // 获取所有文件路径

        // 顺序上传每个文件
        for (const tifFilePath of files) {
          const workspace = 'result'; // 工作区名称
          const { name } = path.parse(tifFilePath);
          const layerName = name;
          const username = 'admin';
          const password = 'geoserver';
          const restUrl = `${this.geoServerURL}/rest/workspaces/${workspace}/coveragestores/${laye_pre}${layerName}${layer_suffix}/file.geotiff`;

          // 构造认证信息
          const auth = `${username}:${password}`;

          // 使用流式读取处理 TIF 文件
          const fileStream = createReadStream(tifFilePath);

          try {
            const response = await axios.put(restUrl, fileStream, {
              headers: {
                'Content-Type': 'image/tiff',
                Authorization: `Basic ${Buffer.from(auth).toString('base64')}`,
              },
              timeout: 60000, // 设置超时为60秒
              httpAgent: agent, // 使用自定义的 HTTP Agent
            });

            if (response) {
              console.log(`Uploaded: ${tifFilePath} - ${response.data}`);
            }
          } catch (uploadError) {
            console.error(`Error uploading ${tifFilePath}:`, uploadError);
          }
        }

        console.log('所有tif发布完成');

        // 根据任务状态进行后续处理
        if (miniTask.pause === false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          // 任务暂停时创建一个 Promise 等待其恢复
          this.promiseService.createPromise(miniTask.id).then(() => {
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          }).catch((err) => {
            console.error('Error after resume:', err);
            reject(err);
          });
        }
      } catch (err) {
        console.error('Error in batch processing:', err);
        this.changeGraphStatus(miniTask.id, process, 'failed');
        reject(err);
      }
    });
  }

  async shpEdit(miniTask: MiniTask, process: Graph) {
    this.changeGraphStatus(miniTask.id, process, 'running');
    return new Promise((resolve, reject) => {
      setTimeout(async () => {
        this.changeGraphStatus(miniTask.id, process, 'success');
        if (miniTask.pause == false) {
          this.changeGraphStatus(miniTask.id, process, 'success');
          resolve('success');
        } else {
          this.changeGraphStatus(miniTask.id, process, 'pause');
          this.promiseService.createPromise(miniTask.id).then(() => {
            console.log('算法执行完成');
            this.changeGraphStatus(miniTask.id, process, 'success');
            resolve('success');
          });
        }
      }, 4000);
    });
  }


  async deleteGraph(id: number) {
    const graph = await this.GraphModel.findOne({
      where: {
        id,
      },
    });
    if (!graph) {
      return {
        succes: false,
        message: '未查询到算法流程',
      };
    }
    let result = await this.GraphModel.remove(graph);
    let MiniTasks = await this.MiniTaskModel.find({
      where: {
        graphId: id,
      },
    });
    MiniTasks.forEach(miniTask => {
      this.MiniTaskModel.remove(miniTask);
    });
    return {
      succes: true,
      data: result,
      message: '删除成功',
    };
  }

  async getNodeParams(id: number, nodeId: string) {
    let miniTask = await this.MiniTaskModel.findOne({
      where: {
        id: nodeId,
        graphId: id,
      },
    });
    if (!miniTask) {
      return {
        succes: false,
        message: '未查询到算法参数',
      };
    }
    return {
      succes: true,
      data: miniTask,
      message: '查询成功',
    };
  }

  async updateNodeParams(id: number, node: IAlgorithmParams) {
    let miniTask = await this.MiniTaskModel.findOne({
      where: {
        id: node.id,
        graphId: id,
      },
    });
    if (!miniTask) {
      return {
        succes: false,
        message: '未查询到算法参数',
      };
    }
    miniTask.runTimeParams = node.runTimeParams;
    let result = this.MiniTaskModel.save(miniTask);
    return {
      succes: true,
      data: result,
      message: '参数修改成功',
    };
  }

  async changePauseStatus(id: number, params: any) {
    let miniTask = await this.MiniTaskModel.findOne({
      where: {
        id: params.id,
        graphId: id,
      },
    });
    if (!miniTask) {
      return {
        succes: false,
        message: '未查询到算法参数',
      };
    }
    miniTask.pause = params.status;
    let result = this.MiniTaskModel.save(miniTask);
    return {
      succes: true,
      data: result,
      message: '暂停状态修改成功',
    };
  }


  async changeParallel(id: number, params: any) {
    let miniTask = await this.MiniTaskModel.findOne({
      where: {
        id: params.id,
        graphId: id,
      },
    });
    if (!miniTask) {
      return {
        succes: false,
        message: '未查询到算法参数',
      };
    }
    miniTask.Parallel = params.Parallel;
    let result = this.MiniTaskModel.save(miniTask);
    return {
      succes: true,
      data: result,
      message: '暂停状态修改成功',
    };
  }

  private async changeGraphStatus(
    miniTaskId: string,
    process: Graph,
    status: string
  ) {
    let graph = JSON.parse(process.graph);
    graph.cells.forEach(element => {
      if (element.id == miniTaskId) {
        element.data.status = status;
      }
    });
    process.graph = JSON.stringify(graph);
    await this.GraphModel.save(process);
    await this.invoke(process.id);
  }
  async resetAllStatus(process: Graph) {
    let graph;
    if (process.isCopyed) {
      graph = process.graph
    } else {
      graph = JSON.parse(process.graph)
    }
    graph.cells && graph.cells.forEach(async element => {
      if (element.shape != 'edge') {
        element.data.status = 'pennding';
        process.graph = JSON.stringify(graph);
        await this.GraphModel.save(process);
        await this.invoke(process.id);
      }
    });
  }
  async resetPartialStatus(process: Graph, cellIds: string[]) {
    let graph = JSON.parse(process.graph);
    let updated = false;
    for (const cell of graph.cells) {
      if (cell.shape !== 'edge' && cellIds.includes(cell.id)) {
        cell.data.status = 'pennding';
        updated = true;
      }
    }

    if (updated) {
      process.graph = JSON.stringify(graph);
      await this.GraphModel.save(process);
      await this.invoke(process.id);
    }
  }

  private extractNumberFromString(str: string): number | null {
    const regex = /(\d+)%/;
    const match = str.match(regex);
    console.log('match' + match);
    let percentage = null;
    if (match) {
      percentage = parseInt(match[1]);
      return percentage;
    }
    return null; // 如果没有找到数字或字符串不符合格式，则返回 null
  }

  private convertJsonArrayToObject(jsonArray) {
    return jsonArray.reduce((result, item) => {
      result[item.param_name] = item.default_value;
      return result;
    }, {});
  }
  private topologicalSort(edges) {
    const graph = {};
    const inDegree = {};

    // 构建图形表示和入度计数
    edges.forEach(edge => {
      const source = edge.source.cell;
      const target = edge.target.cell;

      if (!graph[source]) {
        graph[source] = [];
      }
      graph[source].push(target);

      inDegree[target] = inDegree[target] ? inDegree[target] + 1 : 1;
    });

    const queue = [];
    const executionOrder = [];

    // 将入度为0的节点加入队列
    for (const node in graph) {
      if (!inDegree[node]) {
        queue.push(node);
      }
    }

    // 拓扑排序
    while (queue.length) {
      const node = queue.shift();
      executionOrder.push(node);

      if (graph[node]) {
        graph[node].forEach(neighbor => {
          inDegree[neighbor]--;

          if (inDegree[neighbor] === 0) {
            queue.push(neighbor);
          }
        });
      }
    }

    return executionOrder;
  }
}
